#include "stdafx.h"
#include "GraphicsSystem.h"

using namespace MomogenkyouSystem;

HWND			GraphicsSystem::m_hWnd(NULL);

DEVICEMANAGER	GraphicsSystem::DeviceManager(NULL);
GRAPHICSDEVICE	GraphicsSystem::Device(NULL);
VIEWPORT		GraphicsSystem::ViewPort;
SURFACE			GraphicsSystem::DepthBuffer(NULL);
SURFACE			GraphicsSystem::BackBuffer(NULL);
SPRITEBATCH		GraphicsSystem::SpriteBatch(NULL);


MATRIX			GraphicsSystem::param_matView;						
MATRIX			GraphicsSystem::param_matProjection;				
float4			GraphicsSystem::param_vSunLight(100, 100, 100, 0);


bool	GraphicsSystem::Initialize(const HWND		&	param_WindowHandle,
								   const HINSTANCE	&	param_WindowInstance)
{
	param_matView		=	MomogenkyouHelper::MATRIX_IDENTITY;
	param_matProjection	=	MomogenkyouHelper::MATRIX_IDENTITY;
	

	UNREFERENCED_PARAMETER(param_WindowInstance);
	m_hWnd			=	param_WindowHandle;
	HRESULT	_Result	=	S_OK;
	DeviceManager	=	Direct3DCreate9(D3D_SDK_VERSION);

	ASSERT(DeviceManager != NULL,	"Error Creating D3D9 DeviceManager");

	D3DDISPLAYMODE	_DisplayMode;

	_Result	=	DeviceManager->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &_DisplayMode);
	ASSERT(_Result == S_OK, "Failed to get Direct X Display Mode Adapter");

	D3DPRESENT_PARAMETERS	_PresentParams;
	memset(&_PresentParams, 0x00, sizeof(_PresentParams));

	_PresentParams.BackBufferFormat			=	_DisplayMode.Format; //	D3DFMT_A16B16G16R16	16 bit value
	_PresentParams.EnableAutoDepthStencil	=	false;
	_PresentParams.AutoDepthStencilFormat	=	D3DFMT_D16;
	_PresentParams.Windowed					=	true;
	_PresentParams.SwapEffect				=	D3DSWAPEFFECT_FLIP;
	_PresentParams.PresentationInterval		=	D3DPRESENT_INTERVAL_ONE;
	_PresentParams.hDeviceWindow			=	m_hWnd;
	
	_Result = DeviceManager->CreateDevice(	D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
											m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING,
											&_PresentParams, &Device);

	ASSERT(_Result == S_OK, "Unable to create Graphic Device");

	_Result = Device->CreateDepthStencilSurface(1024, 512, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, true, &DepthBuffer, NULL);
	ASSERT(_Result == S_OK, "Failed to create DepthBuffer");

	Device->SetDepthStencilSurface(DepthBuffer);
	Device->GetRenderTarget(0, &BackBuffer);

	Vertex::InitializeVertexDeclaration();

	Device->GetViewport(&ViewPort);
	ViewPort.X = APP_BORDER_OFFSET_WIDTH >> 1;
	ViewPort.Y = APP_BORDER_OFFSET_WIDTH >> 1;


	//	Setup Default	States
	Device->SetRenderState(D3DRS_ZENABLE, true);
	Device->SetRenderState(D3DRS_LIGHTING, FALSE);  
	Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

	Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	Device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);

	Device->SetRenderState(D3DRS_SRCBLEND,	D3DBLEND_SRCALPHA);
	Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);

	//	Have to apply both Color and Alpha, if not never multiply each other
	/*Device->SetTextureStageState(0, D3DTSS_COLOROP,		D3DTOP_MODULATE);
	Device->SetTextureStageState(0, D3DTSS_COLORARG1,	D3DTA_DIFFUSE);
	Device->SetTextureStageState(0, D3DTSS_COLORARG2,	D3DTA_TEXTURE);*/

	Device->SetTextureStageState(0, D3DTSS_ALPHAOP,		D3DTOP_MODULATE);
	Device->SetTextureStageState(0, D3DTSS_ALPHAARG1,	D3DTA_DIFFUSE);
	Device->SetTextureStageState(0, D3DTSS_ALPHAARG2,	D3DTA_TEXTURE);

	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_GAUSSIANQUAD);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_GAUSSIANQUAD);
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_GAUSSIANQUAD);

	MATRIX	mat;
	D3DXMatrixIdentity(&mat);
	GraphicsSystem::Device->SetTransform(D3DTS_WORLD, &mat);

	D3DXCreateSprite(Device, &SpriteBatch);

	BatchedQuad::PrepareIndexBuffer();
	BatchedQuad::PrepareRender();
	WriteCommandLine("> GraphicsSystem >> Initialized");
	return	true;
}

bool	GraphicsSystem::Shutdown()
{
	BatchedQuad::ReleaseIndexBuffer();
	DepthBuffer->Release();
	BackBuffer->Release();

	SpriteBatch->Release();
	Device->Release();
	DeviceManager->Release();

	m_hWnd	=	NULL;

	WriteCommandLine("> GraphicsSystem >> Shutdown");
	return	true;
}